package com.tg.app.widget;

import android.app.Activity;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.tg.app.R;
import com.tg.app.helper.MultiPlayerHelper;
import com.tg.app.view.CameraPlayerView;
import com.tg.data.bean.DeviceItem;
import com.tg.data.bean.DeviceSettingsInfo;
import com.tg.app.camera.Camera;
import com.tg.data.bean.DeviceSettingsInfo_;
import com.tg.data.media.OnICameraAVListener;
import com.tg.data.media.OnICameraListener;
import com.appbase.custom.constant.CommonConstants;
import com.appbase.custom.constant.DeviceStateConstants;
import com.tg.data.http.entity.AVFrames;
import com.tg.data.media.DefaultVideoDecoder;
import com.tg.data.media.OnMediaPlayListener;
import com.tg.app.util.ObjectBoxUtil;
import com.tg.appcommon.android.TGLog;

import io.objectbox.Box;


/**
 * Describe:
 * Created by Rance Rang on 2019-12-17.
 * <p>
 * Copyright (c) Tange.Inc All rights reserved.
 */
public class SplitScreenPlayer extends LinearLayout implements View.OnClickListener,OnICameraListener, OnICameraAVListener {
    private static final String TAG = "SplitScreenPlayerTAG";
    private Context context;
    private TextureView textureView;
    private Camera camera;
    private DefaultVideoDecoder mediaSync;
    private int nCodecId = 0;
    private boolean surfaceVisible;
    private boolean isPlay;
    private int position;
    private boolean isOffline;
    private ImageView ivStatus,imgBg,ivLoading;
    private TextView tvStatus,tvSleepLock;
    private LinearLayout layoutStatus;
    private DeviceItem device;
    private  int  EVENT_SLEEP = 0x1;
    private DeviceSettingsInfo deviceSettingsInfo;
    private Runnable sleepRunnable;

    // 是否展示画中画的副画面
    private int lastSelectedChannel = -100;
    private boolean shouldShowMini = false;

    private Handler mHandler= new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

    public void setDeviceItem(DeviceItem item) {
        this.device = item;
        if (item!=null){
            isOffline = item.is_online != DeviceStateConstants.DEVICE_ONLINE;
            Glide.with(context).load(item.image_path).thumbnail(0.5f).apply(
                    new RequestOptions().skipMemoryCache(false).dontAnimate()).into(new SimpleTarget<Drawable>() {
                @Override
                public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                    imgBg.setImageDrawable(resource);
                }
            });
        }
       Box<DeviceSettingsInfo> box  = ObjectBoxUtil.getDeviceSettingsInfo();
        if (box!=null){
            deviceSettingsInfo = box.query().equal(DeviceSettingsInfo_.uuid, device.uuid).build().findFirst();
        }

    }

    private OnSplitScreenPlayerListener listener;


    public void setPosition(int position) {
        this.position = position;
    }

    public void setListener(OnSplitScreenPlayerListener listener) {
        this.listener = listener;
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
        this.camera.registerICameraListener(this);
        this.camera.registerCameraAVListener(this);
    }

    public SplitScreenPlayer(Context context) {
        super(context);
        initView(context);
    }

    public SplitScreenPlayer(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public SplitScreenPlayer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context ctx) {
        TGLog.d(TAG, "initView");
        this.context = ctx;
        View view = LayoutInflater.from(ctx).inflate(R.layout.layout_split_screen_player, null);
        addView(view);
        tvSleepLock = view.findViewById(R.id.tv_split_screen_player_sleep_lock);
        ivStatus = view.findViewById(R.id.iv_split_screen_player);
        tvStatus = view.findViewById(R.id.tv_split_screen_player);
        imgBg  = view.findViewById(R.id.iv_split_screen_player_bg);
        ivLoading = view.findViewById(R.id.iv_split_screen_player_loading);
        layoutStatus = view.findViewById(R.id.ll_split_screen_player_layout);
        textureView = view.findViewById(R.id.textureView_split_screen_player);
        tvSleepLock.setOnClickListener(this);
        textureView.setVisibility(View.GONE);
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                TGLog.d(TAG, "onSurfaceTextureAvailable");
                mediaSync.initMediaSync(textureView, nCodecId);
                mediaSync.setPlayType(DefaultVideoDecoder.MEDIA_PLAY_TYPE_CLOUD);

            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

                TGLog.d(TAG, "onSurfaceTextureSizeChanged");
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {

//                surfaceVisible = false;
//                textureView.setVisibility(GONE);
//                ivLoading.setVisibility(GONE);
                mediaSync.stop();
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//
            }
        });
        surfaceVisible = false;
        isPlay = false;
        mediaSync = new DefaultVideoDecoder();
        mediaSync.setPlayListener(new OnMediaPlayListener() {
            @Override
            public void onMediaPlayFirstTimestamp(long pts) {

            }

            @Override
            public void onMediaPlayChanged(boolean isStart) {
                if (!isStart){
                    ((Activity)context).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
//                            surfaceVisible = false;
//                            textureView.setVisibility(GONE);
//                            ivLoading.setVisibility(GONE);
                            if (listener!=null){
                                listener.playerChanged(position);
                            }
                        }
                    });

                }

            }

            @Override
            public void onMediaPlayUpdated(long pts) {

            }



            @Override
            public void onMediaCloudPlayUpdated(long pts) {

            }


        });
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.tv_split_screen_player_sleep_lock){
            tvSleepLock.setVisibility(GONE);
            startShow();
        }

    }

    public void play() {
        if (isOffline){
            layoutStatus.setVisibility(VISIBLE);
            tvStatus.setText(R.string.live_offline);
            ivStatus.setImageResource(R.mipmap.offline);
            return;
        }else if (device!=null&&device.is_open != DeviceStateConstants.DEVICE_OPEN){
            layoutStatus.setVisibility(VISIBLE);
            tvStatus.setText(R.string.camera_closed);
            ivStatus.setImageResource(R.mipmap.device_open);
            return;
        } else {
            layoutStatus.setVisibility(GONE);
        }
        TGLog.d(TAG, "play ");
        if (camera != null && !isPlay) {
            TGLog.d(TAG, "play isPlay ");
            if (camera.isConnected()) {
                isPlay = true;
                startShow();
            } else {
                loading();
                camera.connect();
            }
        }

    }

    private  void startShow(){
        isPlay = true;

        if (lastSelectedChannel == MultiPlayerHelper.UNREAD_VALUE) {
            lastSelectedChannel = MultiPlayerHelper.readChannel(context, camera.uid);
        }

        if (lastSelectedChannel != MultiPlayerHelper.NOT_SELECTED_BEFORE_VALUE) {
            if (lastSelectedChannel == CameraPlayerView.PLAYER_ID_MINI) {
                shouldShowMini = true;
            }
        }

        TGLog.i(TAG, "[startShow] uuid = " + camera.uid);
        TGLog.i(TAG, "[startShow] name = " + camera.deviceName);
        TGLog.i(TAG, "[startShow] lastSelectedChannel = " + lastSelectedChannel);
        TGLog.i(TAG, "[startShow] shouldShowMini = " + shouldShowMini);

        if (shouldShowMini) {
            camera.startShowMini();
        } else {
            camera.startShow();
        }

        if (TextUtils.equals(device.device_type, "sim")) {
            if (sleepRunnable == null) {
                sleepRunnable = new Runnable() {
                    @Override
                    public void run() {
                        camera.stopShow();
                        tvSleepLock.setVisibility(VISIBLE);
                        if (listener!=null){
                            listener.playerChanged(position);
                        }
                    }
                };
            }
            long sleep = CommonConstants.SLEEP_LOCK_TIME_DEFAULT ;
            if (deviceSettingsInfo!=null && deviceSettingsInfo.sleepTime!=0){
                sleep = deviceSettingsInfo.sleepTime;
            }
            mHandler.postDelayed(sleepRunnable, sleep);
        }
    }

    private void loading(){
        ivLoading.setVisibility(VISIBLE);
        AnimationDrawable a = (AnimationDrawable) ivLoading.getDrawable();
        a.start();
    }

    public void stop() {
        if (camera != null && camera.isConnected()) {
            surfaceVisible = false;
            isPlay  = false;
            camera.stopShow();
        }
        mHandler.removeCallbacksAndMessages(sleepRunnable);

        if (camera != null) {
            camera.unregisterICameraListener(this);
        }

        TGLog.d(TAG, "stop");
    }

    public void updateUI() {
        if (surfaceVisible) {
            ivLoading.setVisibility(GONE);
            textureView.setVisibility(View.VISIBLE);
        } else {
            textureView.setVisibility(View.GONE);
        }
        if (isOffline){
            layoutStatus.setVisibility(VISIBLE);
            tvStatus.setText(R.string.live_offline);
            ivStatus.setImageResource(R.mipmap.offline);
        }else {

            if (camera.connectionState ==Camera.CONNECTION_STATE_DISCONNECTED){
                layoutStatus.setVisibility(VISIBLE);
                ivStatus.setImageResource(R.mipmap.live_connection_error);
                TGLog.trace(TAG);
                ivLoading.setVisibility(GONE);
                tvStatus.setText(R.string.live_connection_error);
            }else {
                layoutStatus.setVisibility(GONE);
            }

        }

    }


    @Override
    public void receiveVideoData(AVFrames avFrame) {
        if (avFrame.getMediaCodec()!=0) {
            nCodecId = avFrame.getMediaCodec();
            mediaSync.addVideo(avFrame);
            if (!surfaceVisible && listener != null) {
                surfaceVisible = true;
                TGLog.d(TAG, "receiveVideoData " + camera.deviceName + " position " + position);
                ((Activity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        listener.playerChanged(position);
                    }
                });
            }
        }
    }

    @Override
    public void receiveSubVideoData(AVFrames avFrame) {
        // 这里只会显示一个画面，那重定向给 主画面的处理逻辑 就行了
        if (shouldShowMini) {
            receiveVideoData(avFrame);
        }
    }

    @Override
    public void receiveAudioData(AVFrames avFrame) {

    }

    @Override
    public void receiveUpdateConnectStates(int state) {
        if (state == Camera.CONNECTION_STATE_CONNECTED) {
            startShow();


        }else if (state ==Camera.CONNECTION_STATE_DISCONNECTED){
            isPlay = false;
            ((Activity)context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listener.playerChanged(position);
                }
            });
        }
    }

    @Override
    public void receiveIOCtrlData(int type, byte[] data) {

    }



    public interface OnSplitScreenPlayerListener {
         void playerChanged(int position);
    }
}
